﻿package Util
{
	import flash.utils.ByteArray;
	
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLLoaderDataFormat;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import json.JSON;
	
	/**
	 * PHP 远程调用类
	 */
	public class BinaryRemoting implements IRemoting
	{
		public static const ERROR_NO_SERVICE:int = -101;
		public static const ERROR_NO_FUNCTION:int = -102;
		public static const SUCCESS:int = 1;
		
		private var _url:String;
		private var _path:String;
		
		/**
		 * 远程调用
		 * 
		 * @param String url
		 * @param String path
		 */
		public function BinaryRemoting(url:String, path:String)
		{
			_url = url;
			_path = path;
		}
		
		/**
		 * 更改远程调用包
		 * @param String path
		 */
		public function setPath(path:String)
		{
			_path = path;
		}
		
		/**
		 * 字节流远程调用
		 * 
		 * @param String funcname
		 * @param Array params
		 * @param Function callback
		 */
		public function RemotCall(funcname:String, params:Array, callback:Function)
		{
			var arrPost:Array = new Array();
			arrPost.push(_path);
			arrPost.push(funcname);
			arrPost.push(JSON.encode(params));
			
			var strPost:String = JSON.encode(arrPost);
			
			var binaryPost:ByteArray = new ByteArray();
			binaryPost.writeUTF(strPost);
			binaryPost.compress();
			
			var request:URLRequest = new URLRequest(_url + "?" + Math.random());
			request.contentType = "file";
			request.method = URLRequestMethod.POST;
			request.data = binaryPost;
			
			(function(req:URLRequest){
				var loader:URLLoader = new URLLoader();
				loader.dataFormat = URLLoaderDataFormat.BINARY;
				loader.load(req);
				
				loader.addEventListener(
					Event.COMPLETE, 
					function(event:Event):void
					{
						
						var data:ByteArray = (event.currentTarget.data as ByteArray);
						data.uncompress();
						
						var ret:Object = JSON.decode(data.toString());
						switch(ret[0])
						{
							case SUCCESS:
							{
								callback(ret[1]);
								break;
							}
							case ERROR_NO_SERVICE:
							{
								throw new RemotingError('错误的服务名称', ERROR_NO_SERVICE, _path);
								break;
							}
							case ERROR_NO_FUNCTION:
							{
								throw new RemotingError('错误的方法名称', ERROR_NO_FUNCTION, funcname);
								break;
							}
						}
					}
				);
			})(request);
		}
	}
}